package com.rh.manage.processor;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import com.rh.manage.annotation.ComponentBean;
import com.rh.manage.annotation.FactoryAutowired;
import com.rh.manage.common.View;
import com.rh.manage.constants.FrameCategoryEnum;
import com.rh.manage.listener.FactoryAutowiredListener;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.Field;

/**
 * 从factory上将控件设置到view中
 */
@ComponentBean(FrameCategoryEnum.PRO_MANAGE)
public class FactoryAutowiredBeanPostProcessor implements BeanPostProcessor {

    @Autowired
    private ApplicationContext context;
    @Autowired
    private FactoryAutowiredListener listener;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (!ClassUtil.isAssignable(View.class, bean.getClass())) {
            return bean;
        }
        Field[] fields = ReflectUtil.getFields(bean.getClass());
        if (ArrayUtil.isEmpty(fields)) {
            return bean;
        }
        for (Field field : fields) {
            FactoryAutowired annotation = AnnotationUtil.getAnnotation(field, FactoryAutowired.class);
            if (annotation == null) {
                continue;
            }
            Object factory = context.getBean(annotation.value());
            Field[] factoryFiles = ReflectUtil.getFields(factory.getClass());
            if (ArrayUtils.isEmpty(factoryFiles)) {
                throw new BeanInitializationException("view类[" + bean.getClass().getName() + "]的[" + field.getName()
                        + "]控件没有在factory类[" + factory.getClass().getName() + "]中找到");
            }
            Field targetField = null;
            for (Field factoryField : factoryFiles) {
                if (!ClassUtil.isAssignable(field.getType(), factoryField.getType())) {
                    continue;
                }
                targetField = factoryField;
                break;
            }
            if (targetField == null) {
                throw new BeanInitializationException("view类[" + bean.getClass().getName() + "]的[" + field.getName()
                        + "]控件没有在factory类[" + factory.getClass().getName() + "]中找到");
            }
            Field tempField = targetField; // todo
            Runnable runner = () -> {
                Object fieldValue = ReflectUtil.getFieldValue(factory, tempField);
                if (fieldValue == null) {
                    throw new BeanInitializationException("view类[" + bean.getClass().getName() + "]的[" + field.getName()
                            + "]控件没有在factory类[" + factory.getClass().getName() + "]中找到");
                }
                ReflectUtil.setFieldValue(bean, field, fieldValue);
            };
            listener.add(runner);
        }
        return bean;
    }
}
